Imports vb = Microsoft.VisualBasic

Public Class AppJuego

    Private Const Cero As Integer = 0
    Private Const Uno As Integer = 1
    Private Const Dos As Integer = 2
    Private Const Tres As Integer = 3
    Private Const Cuatro As Integer = 4
    Private Const Cinco As Integer = 5
    Private Const Seis As Integer = 6
    Private Const Siete As Integer = 7
    Private Const Ocho As Integer = 8
    Private Const Nueve As Integer = 9
    Private Const Diez As Integer = 10
    Private Const Catorce As Integer = 14
    Private Const Quince As Integer = 15
    Private Const Veinte As Integer = 20
    Private Const VeintiCinco As Integer = 25
    Private Const TreintaiCinco As Integer = 35
    Private Const Cien As Integer = 100
    Private Const OchoCientos As Integer = 800
    Private Const SeisCientos As Integer = 600

    Public Structure ObjetoNave
        Public x As Integer
        Public y As Integer
        Public Ancho As Integer
        Public Alto As Integer
        Public Estado As String
        Public Imagen As Integer
    End Structure

    Public Structure ObjetoEnemigo
        Public x As Integer
        Public y As Integer
        Public Ancho As Integer
        Public Alto As Integer
        Public Estado As String
        Public Imagen As Integer
        Public Contador As Integer
    End Structure

    Public Structure ObjetoDisparo
        Public x As Integer
        Public y As Integer
        Public Ancho As Integer
        Public Alto As Integer
    End Structure

    Private Structure ObjetoJuego
        Public Estado As String
    End Structure

    Private Juego As ObjetoJuego
    Private Nave As ObjetoNave
    Private Enemigos() As ObjetoEnemigo
    Private Disparos() As ObjetoDisparo
    Private DisparosEnemigos() As ObjetoDisparo
    Private EnemigosY As Integer


    Public GraficoJuego As New Bitmap(OchoCientos, SeisCientos, Drawing.Imaging.PixelFormat.Format24bppRgb)
    Public Canvas As Graphics = Graphics.FromImage(GraficoJuego)



    Private Sub DrawPorComenzar()
        Canvas.Clear(Color.Black)
        Canvas.DrawImage(ImgPorComenzar.Image, Cero, Cero, OchoCientos, SeisCientos)
        ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawGanaste()
        Canvas.Clear(Color.Black)
        Canvas.DrawImage(ImgGanaste.Image, Cero, Cero, OchoCientos, SeisCientos)
        ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawGameOver()
        Canvas.Clear(Color.Black)
        Canvas.DrawImage(ImgGameOver.Image, Cero, Cero, OchoCientos, SeisCientos)
        ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawFondo()
        Canvas.Clear(Color.Black)
        Canvas.DrawImage(ImgFondo.Image, Cero, Cero, OchoCientos, SeisCientos)
        ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawNave()
        If Nave.Imagen >= Cero And Nave.Imagen <= Tres Then
            Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y, Nave.Ancho, Nave.Alto)
            Nave.Imagen = Nave.Imagen + Uno
            'ZonaJuego.Image = GraficoJuego
            Exit Sub
        End If
        If Nave.Imagen >= Cuatro And Nave.Imagen <= Ocho Then
            Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y + Cinco, Nave.Ancho, Nave.Alto - Diez)
            Nave.Imagen = Nave.Imagen + Uno
            'ZonaJuego.Image = GraficoJuego
            Exit Sub
        End If
        If Nave.Imagen >= Nueve And Nave.Imagen <= Catorce Then
            Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y + Diez, Nave.Ancho, Nave.Alto - Veinte)
            Nave.Imagen = Nave.Imagen + Uno
            'ZonaJuego.Image = GraficoJuego
            Exit Sub
        End If
        If Nave.Imagen >= Quince And Nave.Imagen <= Veinte Then
            Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y + Quince, Nave.Ancho, Nave.Alto - 30)
            Nave.Imagen = Nave.Imagen + Uno
            'ZonaJuego.Image = GraficoJuego
            Exit Sub
        End If
        If Nave.Imagen >= 21 And Nave.Imagen <= 26 Then
            Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y + Diez, Nave.Ancho, Nave.Alto - Veinte)
            Nave.Imagen = Nave.Imagen + Uno
            'ZonaJuego.Image = GraficoJuego
            Exit Sub
        End If
        If Nave.Imagen >= 27 And Nave.Imagen <= 32 Then
            Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y + Cinco, Nave.Ancho, Nave.Alto - Diez)
            Nave.Imagen = Nave.Imagen + Uno
            'ZonaJuego.Image = GraficoJuego
            Exit Sub
        End If
        Canvas.DrawImage(ImgNave.Image, Nave.x, Nave.y + Cinco, Nave.Ancho, Nave.Alto - Diez)
        Nave.Imagen = Cero
        'ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawEnemigos()
        Dim Enemigo As ObjetoEnemigo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Enemigo In Enemigos
            If Enemigo.Estado = "vivo" Then
                If Enemigo.Imagen >= Cero And Enemigo.Imagen < Tres Then
                    Canvas.DrawImage(ImgEnemigo1.Image, Enemigo.x, Enemigo.y, Enemigo.Ancho, Enemigo.Alto)
                    Enemigos(Cuenta).Imagen = Enemigo.Imagen + Uno
                ElseIf Enemigo.Imagen >= Cuatro And Enemigo.Imagen < Seis Then
                    Canvas.DrawImage(ImgEnemigo2.Image, Enemigo.x, Enemigo.y, Enemigo.Ancho, Enemigo.Alto)
                    Enemigos(Cuenta).Imagen = Enemigo.Imagen + Uno
                Else
                    Canvas.DrawImage(ImgEnemigo2.Image, Enemigo.x, Enemigo.y, Enemigo.Ancho, Enemigo.Alto)
                    Enemigos(Cuenta).Imagen = Cero
                End If

            End If
            Cuenta = Cuenta + Uno
        Next
        'ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawDisparos()
        Dim Disparo As ObjetoDisparo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Disparo In Disparos
            Canvas.DrawImage(ImgDisparo.Image, Disparo.x, Disparo.y, Disparo.Ancho, Disparo.Alto)
        Next
        'ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub DrawDisparosEnemigos()
        Dim Disparo As ObjetoDisparo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Disparo In DisparosEnemigos
            Canvas.DrawImage(ImgDisparoEnemigo.Image, Disparo.x, Disparo.y, Disparo.Ancho, Disparo.Alto)
        Next
        'ZonaJuego.Image = GraficoJuego
    End Sub



    Private Sub ActualizaEnemigos()

        If Juego.Estado = "porcomenzar" Then
            ReDim Enemigos(Cero)
            ReDim Disparos(Cero)
            ReDim DisparosEnemigos(Cero)
            TiempoAcercarEnemigo.Enabled = False
            Nave.x = 365
            DrawPorComenzar()
            Exit Sub
        End If

        If Juego.Estado = "gameover" Then
            ReDim Enemigos(Cero)
            ReDim Disparos(Cero)
            ReDim DisparosEnemigos(Cero)
            TiempoAcercarEnemigo.Enabled = False
            Nave.x = 365
            DrawGameOver()
            Exit Sub
        End If

        If Juego.Estado = "ganaste" Then
            ReDim Enemigos(Cero)
            ReDim Disparos(Cero)
            ReDim DisparosEnemigos(Cero)
            TiempoAcercarEnemigo.Enabled = False
            Nave.x = 365
            DrawGanaste()
            Exit Sub
        End If



        If Juego.Estado = "iniciando" Then
            Dim Man As Integer
            Dim SubMan As Integer
            EnemigosY = Cero
            For Man = Cero To Diez
                Dim Enemigo As ObjetoEnemigo
                Enemigo.x = (Man * 40) + Cinco
                Enemigo.y = Diez + EnemigosY
                Enemigo.Ancho = TreintaiCinco
                Enemigo.Alto = TreintaiCinco
                Enemigo.Estado = "vivo"
                Enemigo.Imagen = Cero
                Enemigo.Contador = Cero
                ReDim Preserve Enemigos(Man + Uno)
                Enemigos(Man) = Enemigo
            Next
            SubMan = Cero
            For Man = 11 To 21
                Dim Enemigo As ObjetoEnemigo
                Enemigo.x = (SubMan * 40) + Cinco
                Enemigo.y = 45 + EnemigosY
                Enemigo.Ancho = TreintaiCinco
                Enemigo.Alto = TreintaiCinco
                Enemigo.Estado = "vivo"
                Enemigo.Imagen = Tres
                Enemigo.Contador = Cero
                ReDim Preserve Enemigos(Man + Uno)
                Enemigos(Man) = Enemigo
                SubMan = SubMan + Uno
            Next
            SubMan = Cero
            For Man = 22 To 32
                Dim Enemigo As ObjetoEnemigo
                Enemigo.x = (SubMan * 40) + Cinco
                Enemigo.y = 80 + EnemigosY
                Enemigo.Ancho = TreintaiCinco
                Enemigo.Alto = TreintaiCinco
                Enemigo.Estado = "vivo"
                Enemigo.Imagen = Cuatro
                Enemigo.Contador = Cero
                ReDim Preserve Enemigos(Man + Uno)
                Enemigos(Man) = Enemigo
                SubMan = SubMan + Uno
            Next
            SonidoComienzo.Ctlcontrols.stop()
            TiempoAcercarEnemigo.Interval = 10000
            TiempoAcercarEnemigo.Enabled = True
            Juego.Estado = "jugando"
        End If

        Dim EnemigoTemp As ObjetoEnemigo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each EnemigoTemp In Enemigos
            If EnemigoTemp.Estado = "vivo" Then
                Enemigos(Cuenta).Contador = Enemigos(Cuenta).Contador + Uno
                Dim R As Double
                R = Enemigos(Cuenta).Contador * Math.PI / 28
                Enemigos(Cuenta).x = EnemigoTemp.x + Math.Sin(R) * Veinte
            End If
            Dim Retorno As Integer
            Retorno = aleatorio(0, Enemigos.Length * Diez)
            If Retorno = Cuatro Or Retorno = Seis Or Retorno = Ocho Then
                FireEnemigos()
            End If
            Cuenta = Cuenta + Uno
        Next


    End Sub

    Private Sub MoverDisparosEnemigos()
        On Error Resume Next

        'If UBound(Disparos) = 0 Then Exit Sub
        Dim Disparo As ObjetoDisparo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Disparo In DisparosEnemigos
            DisparosEnemigos(Cuenta).y = Disparo.y + VeintiCinco
            Cuenta = Cuenta + Uno
        Next
    End Sub

    Private Sub EliminarDisparosEnemigos()
        On Error Resume Next

        Dim Retorno(Cero) As ObjetoDisparo
        Dim Disparo As ObjetoDisparo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Disparo In DisparosEnemigos
            If Disparo.y < ZonaJuego.Height Then
                ReDim Preserve Retorno(Cuenta + Uno)
                Retorno(Cuenta) = Disparo
                Cuenta = Cuenta + Uno
            End If
        Next
        DisparosEnemigos = Retorno.Clone
    End Sub

    Private Sub FireEnemigos()
        'On Error Resume Next

        Dim Disparo As ObjetoDisparo
        Dim Man As Integer

        Disparo.x = aleatorio(Cero, OchoCientos)
        Disparo.y = 120 + EnemigosY
        Disparo.Ancho = Catorce
        Disparo.Alto = TreintaiCinco
        Man = DisparosEnemigos.Length
        ReDim Preserve DisparosEnemigos(Man)
        DisparosEnemigos(Man - Uno) = Disparo

        'SonidoDisparo.Ctlcontrols.play()

    End Sub

    Private Sub MoverDisparos()
        'On Error Resume Next

        'If UBound(Disparos) = 0 Then Exit Sub
        Dim Disparo As ObjetoDisparo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Disparo In Disparos
            Disparos(Cuenta).y = Disparo.y - VeintiCinco
            Cuenta = Cuenta + Uno
        Next
    End Sub

    Private Sub EliminarDisparos()
        On Error Resume Next

        Dim Retorno(Cero) As ObjetoDisparo
        Dim Disparo As ObjetoDisparo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Disparo In Disparos
            If Disparo.y > Cero Then
                ReDim Preserve Retorno(Cuenta + Uno)
                Retorno(Cuenta) = Disparo
                Cuenta = Cuenta + Uno
            End If
        Next
        Disparos = Retorno.Clone
    End Sub

    Private Sub Fire()
        'On Error Resume Next

        Dim Disparo As ObjetoDisparo
        Dim Man As Integer

        Disparo.x = Nave.x + Diez
        Disparo.y = 540
        Disparo.Ancho = Catorce
        Disparo.Alto = TreintaiCinco
        Man = Disparos.Length
        ReDim Preserve Disparos(Man)
        Disparos(Man - Uno) = Disparo
        SonidoDisparo.Ctlcontrols.play()

    End Sub

    Private Function aleatorio(ByVal Minimo As Integer, ByVal Maximo As Integer) As Integer
        Dim Posibilidades As Integer
        Posibilidades = Maximo - Minimo
        Dim Ret As Double
        Ret = Rnd() * Posibilidades
        Ret = Math.Floor(Ret)
        aleatorio = Minimo + Ret
    End Function

    Private Function hitsNave(a As ObjetoNave, b As ObjetoDisparo) As Boolean
        Dim hit As Boolean = False
        If b.x + b.Ancho >= a.x And b.x < a.x + a.Ancho Then
            If b.y + b.Alto >= a.y And b.y < a.y + a.Alto Then
                hit = True
            End If
        End If
        If b.x <= a.x And b.x + b.Ancho >= a.x + a.Ancho Then
            If b.y <= a.y And b.y + b.Alto >= a.y + a.Alto Then
                hit = True
            End If
        End If
        If a.x <= b.x And a.x + a.Ancho >= b.x + b.Ancho Then
            If a.y <= b.y And a.y + a.Alto >= b.y + b.Alto Then
                hit = True
            End If
        End If
        Return hit
    End Function

    Private Function hitsEnemigo(a As ObjetoEnemigo, b As ObjetoDisparo) As Boolean
        Dim hit As Boolean = False
        If b.x + b.Ancho >= a.x And b.x < a.x + a.Ancho Then
            If b.y + b.Alto >= a.y And b.y < a.y + a.Alto Then
                hit = True
            End If
        End If
        If b.x <= a.x And b.x + b.Ancho >= a.x + a.Ancho Then
            If b.y <= a.y And b.y + b.Alto >= a.y + a.Alto Then
                hit = True
            End If
        End If
        If a.x <= b.x And a.x + a.Ancho >= b.x + b.Ancho Then
            If a.y <= b.y And a.y + a.Alto >= b.y + b.Alto Then
                hit = True
            End If
        End If
        Return hit
    End Function

    Private Function hitsBalas(a As ObjetoDisparo, b As ObjetoDisparo) As Boolean
        Dim hit As Boolean = False
        If b.x + b.Ancho >= a.x And b.x < a.x + a.Ancho Then
            If b.y + b.Alto >= a.y And b.y < a.y + a.Alto Then
                hit = True
            End If
        End If
        If b.x <= a.x And b.x + b.Ancho >= a.x + a.Ancho Then
            If b.y <= a.y And b.y + b.Alto >= a.y + a.Alto Then
                hit = True
            End If
        End If
        If a.x <= b.x And a.x + a.Ancho >= b.x + b.Ancho Then
            If a.y <= b.y And a.y + a.Alto >= b.y + b.Alto Then
                hit = True
            End If
        End If
        Return hit
    End Function

    Private Sub VerificaContacto()
        Dim Disparo As ObjetoDisparo
        Dim Bala As ObjetoDisparo
        Dim Enemigo As ObjetoEnemigo
        Dim CuentaDisparo As Integer
        Dim CuentaBala As Integer
        CuentaDisparo = Cero
        If Juego.Estado = "jugando" Then
            For Each Disparo In Disparos
                CuentaBala = Cero
                For Each Bala In DisparosEnemigos
                    If hitsBalas(Disparo, Bala) = True Then
                        Disparos(CuentaDisparo).y = Cero - Disparos(CuentaDisparo).Alto
                        DisparosEnemigos(CuentaBala).y = ZonaJuego.Height + DisparosEnemigos(CuentaBala).Alto
                    End If
                    CuentaBala = CuentaBala + Uno
                Next
                CuentaDisparo = CuentaDisparo + Uno
            Next

            CuentaDisparo = Cero
            For Each Disparo In Disparos
                CuentaBala = Cero
                For Each Enemigo In Enemigos
                    If Enemigo.Estado = "vivo" Then
                        If hitsEnemigo(Enemigo, Disparo) = True Then
                            Enemigos(CuentaBala).Estado = "hit"
                            Disparos(CuentaDisparo).y = Cero - Disparos(CuentaDisparo).Alto
                            'SonidoColision.Ctlcontrols.play()
                        End If
                    End If
                    CuentaBala = CuentaBala + Uno
                Next
                CuentaDisparo = CuentaDisparo + Uno
            Next
        End If

        If ExistenVivos() = False And Juego.Estado = "jugando" Then
            Juego.Estado = "ganaste"
            SonidoMusicaJuego.Ctlcontrols.stop()
            SonidoGanaste.Ctlcontrols.play()
        End If

        If Juego.Estado = "jugando" Then
            CuentaDisparo = Cero
            For Each Disparo In DisparosEnemigos
                CuentaBala = Cero
                If hitsNave(Nave, Disparo) = True Then
                    Juego.Estado = "gameover"
                    SonidoMusicaJuego.Ctlcontrols.stop()
                    SonidoColisionNave.Ctlcontrols.play()
                    SonidoFinJuego.Ctlcontrols.play()
                End If
                CuentaDisparo = CuentaDisparo + Uno
            Next
        End If

    End Sub

    Private Function ExistenVivos() As Boolean
        ExistenVivos = False
        Dim Enemigo As ObjetoEnemigo

        For Each Enemigo In Enemigos
            If Enemigo.Estado = "vivo" Then
                ExistenVivos = True
                Exit For
            End If
        Next

    End Function

    Private Sub FrameLoop()

        DrawFondo()
        DrawNave()
        ActualizaEnemigos()
        If Juego.Estado = "gameover" Then Exit Sub
        DrawEnemigos()
        MoverDisparos()
        EliminarDisparos()
        MoverDisparosEnemigos()
        EliminarDisparosEnemigos()
        DrawDisparos()
        DrawDisparosEnemigos()
        VerificaContacto()
        ZonaJuego.Image = GraficoJuego
    End Sub

    Private Sub AppJuego_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
        If Juego.Estado = "jugando" Then
            If e.KeyCode = Keys.Space Then
                Fire()
            End If
        End If

        If Juego.Estado = "jugando" Then
            If e.KeyCode = Keys.Left Then
                If Nave.x <= 21 Then Nave.x = Uno Else Nave.x = Nave.x - Veinte
            End If
            If e.KeyCode = Keys.Right Then
                If Nave.x >= 779 - Nave.Ancho Then Nave.x = 799 - Nave.Ancho Else Nave.x = Nave.x + Veinte
            End If
        End If

        If e.KeyCode = Keys.S Then
            If Juego.Estado = "gameover" Or Juego.Estado = "ganaste" Or Juego.Estado = "porcomenzar" Then
                Juego.Estado = "iniciando"
                SonidoMusicaJuego.Ctlcontrols.play()
            End If
        End If
    End Sub

    
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Nave.x = 365
        Nave.y = 525
        Nave.Alto = 75
        Nave.Ancho = TreintaiCinco

        Juego.Estado = "porcomenzar"
        ReDim Disparos(Cero)
        ReDim DisparosEnemigos(Cero)

        On Error Resume Next

        SonidoDisparo.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "Disparo.mp3"
        SonidoColisionCuetes.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "ColisionCuetes.mp3"
        SonidoColisionNave.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "ColisionNave.mp3"
        SonidoColision.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "Colision.mp3"
        SonidoFinJuego.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "Perdido.mp3"
        SonidoGanaste.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "Ganaste.mp3"
        SonidoMusicaJuego.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "MusicaJuego.mp3"
        SonidoComienzo.URL = MFS.RepairFolderPath(MFS.FSOParent(Application.ExecutablePath)) & "BienvenidaAndroidesMalvados.mp3"
        SonidoComienzo.Ctlcontrols.play()


        IntervaloJuego.Interval = 1
        IntervaloJuego.Enabled = True

    End Sub

    Private Sub IntervaloJuego_Tick(sender As Object, e As EventArgs) Handles IntervaloJuego.Tick

        FrameLoop()

    End Sub

    Private Sub LinkPolSoftware_Click(sender As Object, e As EventArgs) Handles LinkPolSoftware.Click

    End Sub

    Private Sub LinkPolSoftware_DoubleClick(sender As Object, e As EventArgs) Handles LinkPolSoftware.DoubleClick
        On Error Resume Next

        Dim Tempo As String
        Tempo = "https://sites.google.com/site/polsoftwareherramientas/home"

        MFS.FileRunCommand(Me.Handle.ToInt32, "EXPLORER.EXE " & Chr(34) & Tempo & Chr(34))

    End Sub


    Private Sub TiempoAcercarEnemigo_Tick(sender As Object, e As EventArgs) Handles TiempoAcercarEnemigo.Tick
        Dim Enemigo As ObjetoEnemigo
        Dim Cuenta As Integer
        Cuenta = Cero
        For Each Enemigo In Enemigos
            If Enemigo.y > ZonaJuego.Height Then Juego.Estado = "gameover" : Exit For
            Enemigos(Cuenta).y = Enemigo.y + TreintaiCinco
            Cuenta = Cuenta + Uno
        Next
        EnemigosY = EnemigosY + TreintaiCinco
    End Sub


    Private Sub ZonaJuego_Click(sender As Object, e As EventArgs) Handles ZonaJuego.Click

    End Sub
End Class
